package com.edu.framework.websocket.service;

import com.alibaba.fastjson2.JSONObject;
import com.edu.common.core.cache.ICache;
import com.edu.common.utils.LogUtils;
import com.edu.framework.websocket.WebSocketHolder;
import com.edu.framework.websocket.assemble.message.MessageAssemble;
import com.edu.framework.websocket.assemble.message.TriggerMsgEngine;
import com.edu.framework.websocket.message.base.Message;
import com.edu.framework.websocket.message.base.Response;
import com.edu.framework.websocket.message.close.CloseRequest;
import com.edu.framework.websocket.message.notice.ForceNoticeRequest;
import com.edu.framework.websocket.message.notice.ForceNoticeVO;
import com.edu.system.service.ITNoticeService;
import com.edu.system.service.ITPublishClassService;
import com.edu.system.service.ITTerminalService;
import java.io.IOException;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.function.Consumer;
import java.util.function.Function;
import javax.annotation.Resource;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.CollectionUtils;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;

/**
 * @program: xxxx
 * @description:
 * @author: zlh
 * @create: 2024-01-06 18:20
 **/
@Slf4j
@Component
public class ForceNoticeService implements MessageAssemble {

  @Resource
  private ITPublishClassService publishClassService;
  @Resource
  private ITNoticeService itNoticeService;
  @Resource
  private ITTerminalService itTerminalService;
  @Resource
  private ICache iCache;
  @Value("${image.host}")
  private String imageHost;

  private static final String CLOSE_ONCE_KEY = "closeOnce_forceNotice_key_%s";
  // 通知// 1通知 2校园风采
  public static final Integer PUBLISH_CLASS_TYPE=1;
  // 1普通通知 2 强通知
  private static final Integer NOTICE_TYPE_NORMAL = 1;
  private static final Integer NOTICE_TYPE_FORCE = 2;

  private Long noticeId;
  /**
   * 强通知
   * @return
   */
  public Response<ForceNoticeVO> getForceNoticeList(Long roomId){
    if (roomId == null){
      return null;
    }

    List<Long> ids = publishClassService.queryIdsByRoomId(roomId, PUBLISH_CLASS_TYPE);
    ForceNoticeVO vo = Optional.ofNullable(itNoticeService.liveListByIds(ids, NOTICE_TYPE_FORCE))
        .filter(CollectionUtils::isNotEmpty)
        .map(a -> a.get(0))
        .map(a -> ForceNoticeVO.builder()
            .id(a.getId())
            .src(LogUtils.mergeHost(imageHost, a.getContent()))
            .build())
        .orElseGet(() -> null);

    String lockKey = String.format(CLOSE_ONCE_KEY, roomId);

    if (vo == null){
      if (iCache.getCacheObject(lockKey) == "1"){
        return null;
      }
      // 打开 关闭锁
      iCache.setCacheObject(lockKey, "1");

      ForceNoticeVO cVo = new ForceNoticeVO();
      cVo.setCloseType(CloseRequest.FORCE_NOTICE);
      return Response.ok(CloseRequest.TYPE, CloseRequest.RESP_KEY, cVo);
    }
    // 有强通知就，关掉 关闭锁
    iCache.setCacheObject(lockKey, "0");

    this.noticeId = vo.getId();
    return Response.ok(ForceNoticeRequest.TYPE, ForceNoticeRequest.RESP_KEY, vo);
  }

  /**
   * 下发通知
   * @param classIds
   * @throws IOException
   */
  public void pushMsg(List<Long> classIds) {
    Map<String, Long> codeMapId = itTerminalService.codeIdMapByLocationIds(null, "班牌");
    Function<String, Message> fc = code -> {
      log.info("机器:{}", code);
      Response<ForceNoticeVO> vo = getForceNoticeList(codeMapId.getOrDefault(code, null));
      log.info("强通知：{}", JSONObject.toJSONString(vo));
      return vo;
    };
    Consumer<Message> invoke = message -> itNoticeService.publishStatusToOn(Arrays.asList(this.noticeId));
    try {
//      WebSocketHolder.broadcastForCode(new ArrayList<>(codeMapId.keySet()), fc, invoke);
      WebSocketHolder.broadcast(fc, invoke);
    } catch (Exception e){
      log.error("主动下发失败 推送通知", e);
    }
  }

  @Override
  public void buildTrigger(List<Long> firstClassIds) {
    TriggerMsgEngine.addEveryRun(ForceNoticeService.class.getSimpleName());
  }

}
